package com.example.sm2.util;

import java.lang.reflect.Field;
import java.util.*;


public class DesensUtils {

    // 定义需要脱敏的字段名
    private static final Set<String> SENSITIVE_FIELDS = new HashSet<>(Arrays.asList(
            "idCard", "phone", "bankCard", "password", "email"
    ));
    /**
     * 对象关键字段脱敏处理
     * @param object 待脱敏处理的对象，可以是实体类或List
     * @return 脱敏后的对象
     */
    public Object desensitizeFields(Object object) {
        if (object == null) {
            return null;
        }

        // 如果是List类型，递归处理每个元素
        if (object instanceof List) {
            List<?> list = (List<?>) object;
            List<Object> desensitizedList = new ArrayList<>(list.size());
            for (Object item : list) {
                desensitizedList.add(desensitizeFields(item));
            }
            return desensitizedList;
        }

        // 处理单个对象
        return desensitizeObjectFields(object);
    }

    /**
     * 对单个对象的关键字段进行脱敏处理
     * @param object 待脱敏对象
     * @return 脱敏后的对象
     */
    private Object desensitizeObjectFields(Object object) {
        if (object == null) {
            return null;
        }

        // 创建对象副本以避免修改原始对象
        Object desensitizedObject;
        try {
            desensitizedObject = object.getClass().getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create instance of object", e);
        }

        // 获取对象的所有字段
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                // 如果字段名在敏感字段列表中且值不为null，则进行脱敏处理
                if (SENSITIVE_FIELDS.contains(field.getName()) && value != null) {
                    String desensitizedValue = desensitizeValue(field.getName(), value.toString());
                    field.set(desensitizedObject, desensitizedValue);
                } else {
                    // 非敏感字段直接复制
                    field.set(desensitizedObject, value);
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Failed to access field: " + field.getName(), e);
            }
        }

        return desensitizedObject;
    }

    /**
     * 对字段值进行脱敏处理
     * @param fieldName 字段名称
     * @param value 字段值
     * @return 脱敏后的值
     */
    private String desensitizeValue(String fieldName, String value) {
        if (value == null || value.isEmpty()) {
            return value;
        }

        switch (fieldName) {
            case "idCard":
                // 身份证号：保留前6位和后4位，中间用*代替
                if (value.length() >= 10) {
                    return value.substring(0, 6) + "*".repeat(value.length() - 10) + value.substring(value.length() - 4);
                } else {
                    return "*".repeat(value.length());
                }
            case "phone":
                // 手机号：保留前3位和后4位，中间用*代替
                if (value.length() >= 7) {
                    return value.substring(0, 3) + "*".repeat(value.length() - 7) + value.substring(value.length() - 4);
                } else {
                    return "*".repeat(value.length());
                }
            case "bankCard":
                // 银行卡号：保留前4位和后4位，中间用*代替
                if (value.length() >= 8) {
                    return value.substring(0, 4) + "*".repeat(value.length() - 8) + value.substring(value.length() - 4);
                } else {
                    return "*".repeat(value.length());
                }
            case "password":
                // 密码：全部用*代替
                return "*".repeat(value.length());
            case "email":
                // 邮箱：@前的字符保留第一位和最后一位，中间用*代替
                int atIndex = value.indexOf('@');
                if (atIndex > 2) {
                    return value.charAt(0) + "*".repeat(atIndex - 2) + value.charAt(atIndex - 1) + value.substring(atIndex);
                } else {
                    return "*".repeat(value.length());
                }
            default:
                // 默认不脱敏
                return value;
        }
    }
}
